unit PacocColourFinders;

{$O+}

interface

uses Windows, Variants, Graphics, Sysutils, Forms, PacocUI, OpenGL;

type
//  TRGB24 = packed Record
//    b,g,r: Byte;
//  end;

//  TRGB24Array = Array [0..MaxInt div SizeOf(TRGB24)-1] of TRGB24;
//  PRGB24Array = ^TRGB24Array;

  TColor32 = 0..16777215;
  TColor32Array = Array [0..3000] of TColor32;
  PColor32Array = ^TColor32Array;

  TPointArray = Array of TPoint;
  TIntegerArray = Array of Integer;

var
  SBMP : TBitmap; //Search bitmap
//  Scanlines: Array {[0..6000]} of PRGB24Array; //scanlines
  Scanlines: Array of PColor32Array;
  bw, bh: Integer;  //what are these?
  I: Integer; //for for loop for getting the scanlines
  BMPDC: HDC;


procedure ColorToRGB(Col: Integer; var R, G, B: Integer);
function  SimilarColors(Col1, Col2, tol: Integer): Boolean;
function  FindColor(var x, y: Integer; color, xs, ys, xe, ye: Integer): Boolean;
function  GetColor(x, y: Integer): Integer;
function  GetColors(Coords: TPointArray): TIntegerArray;

implementation

uses ClickIt, Math;

procedure ColorToRGB(Col: Integer; var R, G, B: Integer);  //make a function?
begin
  R := Col and $ff;
  G := Col shr 8 and $ff;
  B := Col shr 16;
end;

function RGBSimilarColors(R1, G1, B1, R2, G2, B2, tol: Integer): Boolean;//correct?
begin
  Result:= False;
  case ClickIt.CTS of
    0: if(abs(R2 - R1) <= Tol)then
         if(abs(G2 - G1) <= Tol)then
           Result:= abs(B2 - B1) <= Tol;
    1: Result:= Sqrt(sqr(R1 - R2) + sqr(G1 - G2) + sqr(B1 - B2)) <= Tol;
  end;
end;

function SimilarColors(Col1, Col2, tol: Integer): Boolean;
var
  R1, G1, B1, R2, G2, B2: Integer;
begin
  ColorToRgb(col1, R1, G1, B1);
  ColorToRgb(Col2, R2, G2, B2);
  Result := RGBSimilarColors(R1, G1, B1, R2, G2, B2, tol);
end;

{function FindColor(var x, y: Integer; color, xs, ys, xe, ye: Integer): Boolean;
var
  r, g, b, xx, yy, he, wi: integer; //R, G, B: Colour's RGB, XX: search X, yy: search Y, he, wi: searchbmp width/height
  sn, ln: integer;  //StartNummer, LineNumber, EndNumber
  p : PColorArray;   //Array with the colours :)
begin
  //ARE THESE SWAPS NEEDED?  ONLY IDIOTS DON'T KNOW HOW TO USE FINDCOLOR, AND THEY DON'T MATTER
  if (xs > xe) then  //Swap XS and XE if scripter made XS > XE
  begin
    ln:= xe;     //hell, why make another variable when we can just use ln?
    xe := xs;
    xs:= ln;
  end;

  if (ys > ye) then  //Swap YS and YE if scripter made YS > YE
  begin
    ln:= ye;
    ye := ys;
    xs:= ln;
  end;

  if(xs < 0)then xs:= 0;
  if(ys < 0)then ys:= 0;

  if(xe < ClientWdth)then
    wi:= xe-xs
  else
    wi:= ClientWdth - xs;
  if(ye < ClientHght)then
    he:= ye - ys
  else
    he:= ClientHght - ys;
//  sbmp.Width:= wi + 1;
//  sbmp.Height:= he + 1;

//  sbmp.Width := Min(ClientWdth, xe)-xs+1;  //Get width/height
//  sbmp.Height := Min(ClientHght, ye)-ys+1;
//  he := sbmp.Height - 1;    //Assign them to variables (faster!)
//  wi := sbmp.Width - 1;

  asm             //ASM CODE to optimize speed, EAX = a CPU register
    mov eax,color //  eax := color
    and eax,$ff   //  eax := eax and $ff
    mov r, eax    //  r := eax
    mov eax,color //  eax := color
    shr eax,8     //  eax := eax shr 8
    and eax,$ff   //  eax := eax and $ff
    mov g,eax     //  r := eax
    mov eax,color //  eax := color
    shr eax,16    //  eax := eax shr 16
    mov b,eax     //  b := eax;
  end;            //END ASM CODE

  BitBlt(SBMP.Canvas.Handle, 0, 0, wi + 1, he + 1, ClickIt.ClientDC, {xs, ys}{ 0, 0, SRCCopy); //Copy bitmap we gonna search in

  P := sbmp.ScanLine[0];
  ln:= -bw{ - 1}{;
  sn:= -ln;
  for yy:= ys to ye do
  begin
    sn:= sn + ln;
    for xx:= sn + xs to sn + xe do
      if (p[xx].r = R) then
        if (p[xx].g = G) then
          if (p[xx].b = B) then
          begin
            x := xx - sn + xs;
            y := yy;
            result := true;
            exit;
          end;
    end;
  x:= -1;
  y:= -1;
  Result:= False;
end;}

function FindColor(var x, y: Integer; color, xs, ys, xe, ye: Integer): Boolean;
var
  xx, yy: Integer;
//  R, G, B: Byte;
begin
  if (xs > xe) then  //Swap XS and XE if scripter made XS > XE
  begin
    xx:= xe;
    xe := xs;
    xs:= xx;
  end;

  if (ys > ye) then  //Swap YS and YE if scripter made YS > YE
  begin
    xx:= ye;
    ye := ys;
    ys:= xx;
  end;

//  R:= color;
//  G:= color shr 8;
//  B:= color shr 16;

//  color:= R shl 16 + G shl 8 + B;

  {asm
    mov eax, color
    and eax, $ff
    shl eax, 16
    mov ebx, color
    and ebx, $ff00
    mov ecx, color
    shr ecx, 16
    mov rbx, eax
    add rbx, ebx
    add rbx, ecx
    mov color, ax
  end; }

  color:= ((color and $ff) shl 16) + (color and $ff00) + (color shr 16);

//  PacocUI.Writeln(inttostr(Integer(ClickIt.ClientDC)));

  BitBlt(SBMP.Canvas.Handle, xs, ys, xe - xs, ye - ys, ClickIt.ClientDC, xs, ys, SRCCOPY);

  for yy:= ys to ye do
    for xx:= xs to xe do
//      if(Scanlines[yy][xx].R = R)then if(Scanlines[yy][xx].G = G)then if(Scanlines[yy][xx].B = B)then
      if(Scanlines[yy][xx] = color)then
      begin
        x:= xx;
        y:= yy;
        Result:= True;
        exit;
      end;
  Result:= False;
  x:= -1;
  y:= -1;
end;

function GetColor(x, y: Integer): Integer;
begin
  Result:= GetPixel(ClickIt.ClientDC, x, y);
end;                        

function GetColors(Coords: TPointArray): TIntegerArray;
var
  I, C: Integer;
begin
  C:= 0;
  SetLength(Result, Length(Coords));
  for I:= Low(Coords) to High(Coords) do
  begin
    Result[C]:= GetPixel(ClickIt.ClientDC, Coords[I].X, Coords[I].Y);
    C:= C + 1;
  end;
end;

initialization
  SBMP := TBitmap.Create; //Create the search bitmap
  SBMP.Width:= Screen.Width;
  SBMP.Height:= Screen.Height;
  SBMP.PixelFormat:= pf32bit;
  SetLength(Scanlines, SBMP.Height);
  for I:= 0 to SBMP.Height - 1 do
    Scanlines[I]:= SBMP.ScanLine[I];
//  BMPDC:= SBMP.Canvas.Handle;
end.
